const jsonwebtoken = require('jsonwebtoken')
const User = require('../models/user')
const Question = require('../models/Question.js')
const Answer = require('../models/answers')
const { secret } = require('../config')

class UserCtl {
  /**
   * 获取用户列表
   * @param {Object} ctx 
   */
  async find(ctx) {
    const { per_page = 3 } = ctx.query
    const page = Math.max(ctx.query.page * 1, 1) - 1
    const perPage = Math.max(per_page * 1, 1)
    ctx.body = await User
      .find({ name: new RegExp(ctx.query.q) })
      .limit(perPage).skip(page * perPage)
  }
  /**
   * 获取某一个用户的具体信息
   * @param {Object} ctx 
   */
  async findById(ctx) {
    const { filelds = '' } = ctx.query
    const selectFields = filelds.split(';').filter(f => f).map(f => ' +' + f).join('')
    const populateStr = filelds.split(';').filter(f => f).map(f => {
      if (f === 'employments') {
        return 'employments.company employments.job'
      }
      if (f === 'educations') {
        return 'educations.school educations.major'
      }
      return f;
    }).join(' ')
    const user = await User.findById(ctx.params.id).select(selectFields)
      .populate(populateStr)
    if (!user) {
      ctx.throw(404, '用户不存在')
    }
    ctx.body = user
  }
  /**
   * 创建用户
   * @param {Object} ctx 
   */
  async create(ctx) {
    ctx.verifyParams({
      name: { type: 'string', required: true },
      password: { type: 'string', required: true }
    })
    const { name } = ctx.request.body
    const repeatedUser = await User.findOne({ name })
    if (repeatedUser) {
      ctx.throw(409, '该用户已存在')
    } else {
      const user = await new User(ctx.request.body).save()
      ctx.body = user
    }
  }
  /**
   * 检查当前操作用户是否为登录用户
   * @param {Object} ctx 
   * @param {Object} next 
   */
  async checkOwner(ctx, next) {
    if (ctx.params.id !== ctx.state.user._id) {
      ctx.throw(403, '没有权限')
    }
    await next()
  }
  /**
   * 修改某一个用户的信息
   * @param {Object} ctx 
   */
  async update(ctx) {
    ctx.verifyParams({
      name: { type: 'string', required: false },
      password: { type: 'string', required: false },
      avatar_url: { type: 'string', required: false },
      gender: { type: 'string', required: false },
      headline: { type: 'string', required: false },
      locations: { type: 'array', itemType: 'string', required: false },
      business: { type: 'string', required: false },
      employments: { type: 'array', itemType: 'object', required: false },
      educations: { type: 'array', itemType: 'object', required: false },
    })
    const user = await User.findByIdAndUpdate(ctx.params.id,
      ctx.request.body)
    if (!user) {
      ctx.throw(404, '查找用户不存在')
    }
    ctx.body = user
  }
  /**
   * 删除某一个用户
   * @param {Object} ctx 
   */
  async delete(ctx) {
    const user = await User.findByIdAndDelete(ctx.params.id)
    if (!user) {
      ctx.throw(404, '删除未成功')
    }
    ctx.status = 204
  }
  /**
   * 登录
   * @param {Object} ctx 
   */
  async login(ctx) {
    ctx.verifyParams({
      name: { type: 'string', required: true },
      password: { type: 'string', required: true }
    })
    const user = await User.findOne(ctx.request.body)
    if (!user) {
      ctx.throw(401, '用户不存在或密码不正确')
    }
    const { _id, name } = user
    const token = jsonwebtoken.sign({ _id, name }, secret, {
      expiresIn: '12h'
    })
    ctx.body = { token }
  }
  /**
   * 某一用户的关注者列表
   * ctx.params.id 用户 ID
   * @param {Object} ctx 
   */
  async listFollowing(ctx) {
    const user = await User.findById(ctx.params.id).select('+following').populate('following')
    if (!user) {
      ctx.throw(404)
    }
    ctx.body = user.following
  }
  /**
   * 检查用户是否存在
   * @param {Object} ctx 
   * @param {Object} next 
   */
  async checkUserExist(ctx, next) {
    const user = await User.findById(ctx.params.id)
    if (!user) {
      ctx.throw(404, '用户不存在')
    }
    await next()
  }
  /**
   * 关注某个人
   * ctx.state.user._id，解析 token 之后获取到
   * @param {Object} ctx 
   */
  async follow(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+following')
    if (!me.following.map(id => id.toString()).includes(ctx.params.is)) {
      me.following.push(ctx.params.id)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   * 取消某个人
   * ctx.state.user._id，解析 token 之后获取到
   * @param {Object} ctx 
   */
  async unfollow(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+following')
    const index = me.following.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.following.splice(index, 1)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   * 某个用户的粉丝列表
   * @param {Object} ctx 
   */
  async listFollowers(ctx) {
    const users = await User.find({ following: ctx.params.id })
    ctx.body = users
  }
  /**
   * 某一个用户关注话题
   * @param {Object} ctx 
   */
  async followTopic(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+followingTopics')
    if (!me.followingTopics.map(id => id.toString()).includes(ctx.params.id)) {
      me.followingTopics.push(ctx.params.id)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   * 某一个用户取消关注话题
   * @param {Object} ctx 
   */
  async unfollowTopic(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+followingTopics')
    const index = me.followingTopics.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.followingTopics.splice(index, 1)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   * 某一个用户关注的话题列表
   * @param {Object} ctx 
   */
  async listFollowingTopics(ctx) {
    const user = await User.findById(ctx.params.id).select('+following').populate('followingTopics')
    if (!user) {
      ctx.throw(404, '话题不存在')
    }
    ctx.body = user.followingTopics
  }
  /**
   * 某一个用户的问题列表
   * @param {Object} ctx 
   */
  async listQuestions(ctx) {
    const questions = await Question.find({ questioner: ctx.params.id })
    ctx.body = questions
  }
  /**
   * 某一个用户点赞的答案列表
   * (传入用户 ID)
   * @param {Object} ctx 
   */
  async listLikingAnswers(ctx) {
    const user = await User.findById(ctx.params.id).select('+likingAnswers').populate('likingAnswers')
    if (!user) {
      ctx.throw(404, '不存在')
    }
    ctx.body = user.likingAnswers

  }
  /**
   * 点赞答案
   * @param {Object} ctx 
   * @param {Object} next 
   */
  async likeAnswers(ctx, next) {
    const me = await User.findById(ctx.state.user._id).select('+likingAnswers')
    console.log(me)
    if (!me.likingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.likingAnswers.push(ctx.params.id)
      me.save()
      await Answer.findByIdAndUpdate(ctx.params.id, { $inc: { voteCount: 1 } })
    }
    ctx.state.me = me
    ctx.body = '成功'
    await next()
  }
  /**
   * 取消点赞答案
   * @param {Object} ctx 
   */
  async unlikeAnswers(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+likingAnswers')
    const index = me.likingAnswers.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.likingAnswers.splice(index, 1)
      me.save()
      await Answer.findByIdAndUpdate(ctx.params.id, { $inc: { voteCount: -1 } })
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   *  踩答案列表
   * @param {Object} ctx 
   */
  async listDisLikingAnsers(ctx) {
    const user = await User.findById(ctx.params.id).select('+dislikingAnswers').populate('dislikingAnswers')
    console.log(user)
    if (!user) {
      ctx.throw(404, '话题不存在')
    }
    ctx.body = user.dislikingAnswers
  }
  /**
   * 踩答案
   * @param {Object} ctx 
   * @param {Object} next 
   */
  async dislikeAnswers(ctx, next) {
    console.log('dislikeAnswers', ctx.state.user)
    const me = await User.findById(ctx.state.user._id).select('+dislikingAnswers')
    if (!me.dislikingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.dislikingAnswers.push(ctx.params.id)
      me.save()
    }
    ctx.state.me = me
    ctx.body = '成功'
    await next()
  }
  /**
   * 取消踩答案
   * @param {Object} ctx 
   */
  async disunlikeAnswers(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+dislikingAnswers')
    const index = me.dislikingAnswers.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.dislikingAnswers.splice(index, 1)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
  /**
   * 某一个用户的收藏答案列表
   * @param {Object} ctx 
   */
  async listCollectingAnswers(ctx) {
    const user = await User.findById(ctx.params.id).select('+collectingAnswers').populate('collectingAnswers')
    if (!user) {
      ctx.throw(404, '收藏答案不存在')
    }
    ctx.body = user.collectingAnswers
  }
  /**
   * 收藏答案
   * @param {Object} ctx 
   * @param {Object} next 
   */
  async collectAnswers(ctx, next) {
    const me = await User.findById(ctx.state.user._id).select('+collectingAnswers')
    if (!me.collectingAnswers.map(id => id.toString()).includes(ctx.params.id)) {
      me.collectingAnswers.push(ctx.params.id)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
    await next()
  }
  /**
   * 取消收藏答案
   * @param {Object} ctx 
   */
  async uncollectAnswers(ctx) {
    const me = await User.findById(ctx.state.user._id).select('+collectingAnswers')
    const index = me.collectingAnswers.map(id => id.toString()).indexOf(ctx.params.id)
    if (index > -1) {
      me.collectingAnswers.splice(index, 1)
      me.save()
    }
    ctx.state = 204
    ctx.body = '成功'
  }
}

module.exports = new UserCtl()